﻿using Syspetro.Core.AppDeal;
using Syspetro.Core.ErrorException;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Syspetro.Core.DbAccessor
{
    public abstract class EntityBaseService<T> : IEntityBaseService<T> where T : EntityBase, new()
    {
        public abstract IRepository<T> Repository { get; }

        #region 添加
        public virtual Task<Guid> AddAsync(T model)
        {
            if (model == null)
                throw new ExceptionTypeError();
            return Repository.AddAsync(model);
        }
        public virtual Task<int> AddAsync(List<T> models)
        {
            if (models == null)
                throw new ExceptionTypeError();
            Repository.AddTrans(models);
            return Repository.SaveAsync;
        }
        #endregion

        #region 删除
        public virtual Task<bool> DeleteAsync(T model)
        {
            if (model == null)
                throw new ExceptionTypeError();
            return Repository.DeleteAsync(model.Id);
        }
        public virtual Task<bool> DeleteAsync(Guid id)
        {
            return Repository.DeleteAsync(id);
        }
        public virtual Task<int> DeleteAsync(Expression<Func<T, bool>> expression)
        {
            return Repository.DeleteAsync(expression);
        }
        #endregion

        #region 修改
        public virtual Task<bool> UpdateAsync(T model)
        {
            if (model == null)
                throw new ExceptionTypeError();
            return Repository.UpdateAsync(model);
        }
        public async Task<bool> UpdateAsync<V>(V model, Expression<Func<T, bool>> expression) where V : class, new()
        {
            if (model == null)
                throw new ExceptionTypeError();
            if (expression == null)
                throw new ExceptionTypeError("expression参数不能为空");
            var i = await Repository.UpdateDtoAsync<V>(model, expression);
            return i > 0;
        }
        public virtual Task<bool> UpdateAsync(T model, Expression<Func<T, object>> properties, bool isIgnore = false)
        {
            if (model == null)
                throw new ExceptionTypeError();
            if (properties == null)
                properties = t => t.Id == model.Id;
            return Repository.UpdateAsync(model, properties, isIgnore);
        }
        public virtual Task<int> UpdateAsync(T model, Expression<Func<T, bool>> expression, Expression<Func<T, object>> properties)
        {
            if (model == null)
                throw new ExceptionTypeError();
            if (expression == null)
                expression = t => t.Id == model.Id;
            return Repository.UpdateAsync(model, expression, properties);
        }
        #endregion

        #region 查询
        public virtual Task<bool> AnyAsync(Expression<Func<T, bool>> expression)
        {
            return Repository.AnyAsync(expression);
        }
        public virtual Task<T> GetAsync(Guid id)
        {
            return Repository.GetAsync(id);
        }
        public Task<V> GetDtoAsync<V>(Guid id) where V : class, new()
        {
            return Repository.GetDtoAsync<V>(id);
        }
        public virtual Task<List<T>> FindAsync(Expression<Func<T, bool>> expression, IOrderByReq orderBy = null)
        {
            if (orderBy == null)
                return Repository.FindAsync(expression);
            else
                return Repository.FindAsync(expression, orderBy.OrderBy, orderBy.IsAscending());
        }
        public virtual Task<List<V>> FindDtoAsync<V>(Expression<Func<T, bool>> expression, IOrderByReq orderBy = null) where V : class, new()
        {
            if (orderBy == null)
                return Repository.FindDtoAsync<V>(expression);
            else
                return Repository.FindDtoAsync<V>(expression, orderBy.OrderBy, orderBy.IsAscending());
        }
        public virtual async Task<PageList<T>> FindPageAsync(IPageReq<T> req)
        {
            var list = await Task.FromResult(Repository.FindPage(out int total, req.GetWhereExpression(), req.OrderBy, req.Current, req.Size, req.IsAscending()));
            return new PageList<T>
            {
                Size = req.Size,
                Current = req.Current,
                Total = total,
                Records = list
            };
        }
        public virtual async Task<PageList<V>> FindPageAsync<V>(IPageReq<T> req) where V : class, new()
        {
            var list = await Task.FromResult(Repository.FindPageDto<V>(out int total, req.GetWhereExpression(), req.OrderBy, req.Current, req.Size, req.IsAscending()));
            return new PageList<V>
            {
                Size = req.Size,
                Current = req.Current,
                Total = total,
                Records = list
            };
        }
        #endregion
    }
}
